import { errorCode } from '@/constant/dict';

function dec2hex(textString) {
    return (textString + 0).toString(16).toUpperCase();
}

function getCurrentTime() {
    let date = new Date();
    let month = zeroFill(date.getMonth() + 1);
    let day = zeroFill(date.getDate());
    let hour = zeroFill(date.getHours());
    let minute = zeroFill(date.getMinutes());
    let second = zeroFill(date.getSeconds());
    let curTime = date.getFullYear() + '-' + month + '-' + day + ' ' + hour + '_' + minute + '_' + second;
    return curTime;
}
function zeroFill(i) {
    if (i >= 0 && i <= 9) {
        return '0' + i;
    } else {
        return i;
    }
}

function fileName(name, type = '.txt') {
    let fileDataName = name + getCurrentTime() + type;
    return fileDataName;
}

export function saveLogFileFun(name, value, type) {
    let blob = new Blob([value]);
    if ('msSaveOrOpenBlob' in navigator) {
        window.navigator.msSaveOrOpenBlob(blob, fileName(name, type));
    } else {
        let url = window.URL.createObjectURL(blob);
        let link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', fileName(name, type));
        link.click();
    }
}


/**
 * unicode编码(不支持表情包)
 * @method encodeMessage
 * @param textString {String}
 * @return {String}
 */
export function submitEncodeMessage(textString) {
    let haut = 0;
    let result = '';
    if (!textString) return result;
    for (let i = 0; i < textString.length; i++) {
        let b = textString.charCodeAt(i);
        if (haut != 0) {
            if (0xdc00 <= b && b <= 0xdfff) {
                result += dec2hex(0x10000 + ((haut - 0xd800) << 10) + (b - 0xdc00));
                haut = 0;
                continue;
            } else {
                haut = 0;
            }
        }
        if (0xd800 <= b && b <= 0xdbff) {
            haut = b;
        } else {
            let cp = dec2hex(b);
            while (cp.length < 4) {
                cp = '0' + cp;
            }
            result += cp;
        }
    }
    return result;
}

//特殊字符转义
export function html2Escape(sHtml) {
    return sHtml.replace(/[<>"']/g, function (c) {
        return { '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
    });
}

/**
 * 特殊字符转义
 * @param {标题内容} title
 * @returns
 */
export function htmltoEscape(title) {
    if (parent.html2Escape) {
        return parent.html2Escape(title);
    }
    return title;
}

/**
 * @description 校验规则：1、校验ASCII值，32-126；2、不允许输入 '`', '$', '(', ')', '|', '&'
 * @param {String} str 需要校验的字符串
 * @param {Boolean} allowEs 是否允许输入西班牙语，默认允许
 * @param {Boolean} isSpStr 是否校验特殊字符，默认是
 * @param {Boolean} isAcsll 是否校验 Acsll 码，默认是
 * @param {Boolean} isSpace 是否校验空格，1、校验 Acsll 码时，默认为true；2、不校验 Acsll 码时，默认为false
 * @param {Number} maxByte 需要限制的字节数，默认 32 字节
 * @param {Number} startCode ASCII起始值，默认 32
 * @param {Number} endCode ASCII结束值，默认 126
 * @param {Number} minByte 需要限制的字节数，默认 0 字节
 * @returns Boolean || String
 */
export function checkStr(str, allowEs = true, isSpStr = true, isAcsll = true, isSpace = false, maxByte = 32, startCode = 32, endCode = 126, minByte = 0) {
    if (str) {
        // 手动转换一次String,以防传的不是字符串
        const toStr = String(str);
        // 获取字节长度
        const strByte = getByteLength(toStr);
        // 校验特殊字符
        if (isSpStr) {
            if (!checkSpStr(toStr)) {
                return errorCode.STRERR;
            }
        }
        if (strByte >= minByte && strByte <= maxByte) {
            for (let char of toStr) {
                const charCode = char.charCodeAt(0);
                if (allowEs) {
                    if (charCode < startCode || charCode > endCode) {
                        if (charCode < 161 || charCode > 255) {
                            return errorCode.ACCIIERR;
                        }
                    }
                } else {
                    if (isAcsll) {
                        if (charCode < startCode || charCode > endCode) {
                            return errorCode.ACCIIERR;
                        }
                    } else {
                        if (isSpace && charCode == 32) {
                            return errorCode.ACCIIERR;
                        }
                    }
                }
            }
        } else {
            return errorCode.BYTEERR;
        }
        return true;
    }
    return false;
}

/**
 * @description 校验字符串字节长度,UTF-8
 * @param {String} str
 * @returns Number
 */
export function getByteLength(str) {
    let totalBytes = 0;
    let charCode;
    let i;

    for (i = 0; i < str.length; i++) {
        charCode = str.charCodeAt(i);
        if (charCode < 0x007f) {
            totalBytes += 1;
        } else if (charCode >= 0x0080 && charCode <= 0x07ff) {
            totalBytes += 2;
        } else if (charCode >= 0x0800 && charCode <= 0xffff) {
            totalBytes += 3;
        } else {
            totalBytes += 4;
        }
    }

    return totalBytes;
}

/**
 * @description 校验特殊字符，不允许输入 '`', '$', '(', ')', '|', '&'
 * @param {String} str
 * @returns Boolean || String
 */
export function checkSpStr(str) {
    if (str) {
        const toStr = String(str);
        for (let char of toStr) {
            if (['`', '$', '(', ')', '|', '&'].includes(char)) {
                return false;
            }
        }
        return true;
    }
    return false;
}

/**
 * @description 通用常规名称校验
 * @param {*} str 需要校验的字符串
 * @param {*} bytesMax 能通过的最大字节，默认32
 * @returns errorCode String || Boolean
 */
export function nameCheck(str, bytesMax = 32) {
    if (!str) return false;
    const checkSpStrStatus = checkSpStr(str);
    const totalBytes = getByteLength(str);
    if (totalBytes > bytesMax) {
        return errorCode.BYTEERR;
    }
    return checkSpStrStatus && totalBytes <= bytesMax;
}

/**
 * @description 校验是否存在空格
 * @param {String} str
 * @returns Boolean
 */
export function checkSpace(str) {
    if (str) {
        const toStr = String(str);
        for (let char of toStr) {
            const charCode = char.charCodeAt(0);
            if (charCode == 32) {
                return false;
            }
        }
        return true;
    }
    return false;
}

/**
 * @description 判断数组是否有重复值
 * @param arr 要判断的数组
 * @param newItem 当前判断的对象
 * @param field 要判断重复的字段
 * @param editingItem 当前编辑项
 * @returns boolean true有重复，false没有重复
 */
export function hasDuplicateItem(arr, newItem, key, editingItem) {
    return arr.some((item) => item[key].toLowerCase() === newItem[key].toLowerCase() && item !== editingItem && item !== newItem && newItem[key]);
}

/**
 * @description 根据后端描述，需要定义一个二维数组的，然后通过判断list是否在这个字典中，来调用不同的接口
 */
export const IDSTACK_NODE = {
    LIST_DEV_HOST_AC: 33
};

/**
 * 格式化IP、MASK等，自动去掉前缀0
 * @param {String} ipStr
 * @returns
 */
export function formIp(ipStr) {
    if (typeof ipStr != 'string') {
        throw new Error(errorCode.PARAMETERERR);
    }

    const ipArr = ipStr.split('.');

    if (ipArr.length < 4) {
        throw new Error(errorCode.IPERR);
    }

    return ipArr
        .map((ip) => {
            const ipNum = Number(ip);
            if (isNaN(ipNum) || ipArr.includes('') || ipArr.includes(' ') || ipNum < 0 || ipNum > 255) {
                throw new Error(errorCode.IPERR);
            }
            return ipNum;
        })
        .join('.');
}

// 短轮询工具函数定时器 ID
let SHORT_TIMER_ID = null;

/**
 * 到时自动停止的短轮询工具函数，Return 一个停止轮询的函数
 * @param {Function} callback 回调函数
 * @param {Number} totalDuration 持续时间（以毫秒为单位）
 * @param {Number} callInterval 轮询间隔（以毫秒为单位）
 */
export function shortPolling(callback, totalDuration, callInterval = 2000) {
    // 停止标志
    let stopFlag = false;

    // 开始时间
    const startTime = Date.now();

    // 清除轮询
    const stopPolling = () => {
        if (SHORT_TIMER_ID) {
            clearInterval(SHORT_TIMER_ID);
        }
        stopFlag = true;
    };

    // 清除上一次轮询，防止叠加
    stopPolling();

    // 重置停止标志
    stopFlag = false;

    // 立即回调一次
    callback();

    // 开始轮询
    SHORT_TIMER_ID = setInterval(() => {
        const elapsedTime = Date.now() - startTime;

        if (elapsedTime < totalDuration && !stopFlag) {
            callback();
        } else {
            stopPolling();
        }
    }, callInterval);

    return stopPolling;
}

/**
 * 根据 keys 提取 object 中指定属性
 * @param {Object} object
 * @param {Array} keys
 * @returns
 */
export function extractProperties(object, keys) {
    const result = {};
    keys.forEach((key) => {
        result[key] = object[key];
    });
    return result;
}

/**
 * 检测是否有shell中的特殊字符，如果有的话就在前面添加 \转义
 */

export function escapeShellSpecialChars(str) {
    if (!str) return str;
    // 使用eslint-disable-line来忽略当前行的no-useless-escape警告
    const specialChars = /[\$``\"\'\\;|&(){}[\]<>?*#~!]/g; // eslint-disable-line no-useless-escape

    // 使用正则表达式的replace方法替换找到的每个特殊字符
    return str.replace(specialChars, '\\$&');
}
